﻿using System;
using System.Linq;
using System.Threading.Tasks;
using Elsa.Services.Models;
using HengTong.Model;
using HengTong.Model.Db.Hr;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using TiaoTaoHelper.Wtm.Workflow;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.WorkFlow;

namespace HengTong.ViewModel.Hr.SysHrProbationRequestBillVms;

public partial class SysHrProbationRequestBillVm
{
    [WorkflowOperation("驳回", "将单据状态设置为草稿", "转正申请")]
    public async Task Reject(ActivityExecutionContext context)
    {
        Entity.BillStatus = BillStatus.草稿;
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        DC.UpdateProperty(Entity, x => x.BillStatus);
        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("取消", "将流程状态设置为取消", "转正申请")]
    public async Task Cancel(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已取消;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("完成", "将流程状态设置为已完成", "转正申请")]
    public async Task Complete(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已完成;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("完成并更新档案", "将流程状态设置为已完成并更新人员转正信息", "转正申请")]
    public async Task CompleteAndUpdateArchive(ActivityExecutionContext context)
    {
        // 获取日志记录器
        using var scope = Wtm.ServiceProvider.CreateScope();
        var logger = scope.ServiceProvider.GetRequiredService<ILogger<SysHrProbationRequestBillVm>>();

        // 获取当前操作用户
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
        {
            currentUser = input.CurrentUser?.ITCode ?? "workflow";
        }

        logger.LogInformation("开始执行转正申请完成操作，单据ID：{EntityId}，工号：{StaffNo}，操作用户：{User}",
            Entity?.ID, Entity?.StaffNo, currentUser);

        using var transactionScope = new System.Transactions.TransactionScope(
            System.Transactions.TransactionScopeOption.Required,
            new System.Transactions.TransactionOptions
            {
                IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted,
                Timeout = TimeSpan.FromMinutes(5)
            },
            System.Transactions.TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            // 检查当前工号是否是试用期
            var person = await DC.Set<SysPerson>()
                .Where(x => x.GetType() == typeof(SysPerson))
                .Where(p => p.StaffNo == Entity.StaffNo && p.State == PersonState.试用期)
                .FirstOrDefaultAsync();

            if (person == null)
            {
                logger.LogError("工号 {StaffNo} 不在试用期，无法完成转正操作", Entity.StaffNo);
                throw new Exception($"工号 {Entity.StaffNo} 不在试用期，无法完成转正操作");
            }

            // 更新人员档案的转正信息
            DC.Set<SysPerson>()
                .Where(x => x.GetType() == typeof(SysPerson))
                .Where(p => p.ID == person.ID)
                .ExecuteUpdateAsync(p => p
                    .SetProperty(x => x.State, PersonState.在职)
                    .SetProperty(x => x.HireDate, Entity.EntryDate ?? DateTime.Now)
                    .SetProperty(x => x.ConfirmationDate, Entity.RegDate ?? DateTime.Now)
                    .SetProperty(x => x.UpdateTime, DateTime.Now)
                    .SetProperty(x => x.UpdateBy, currentUser));
            logger.LogInformation("成功更新人员档案信息，工号：{StaffNo}，转正日期：{RegularDate}",
                Entity.StaffNo, Entity.RegDate ?? DateTime.Now);

            Entity.WorkflowStatus = WorkflowStatus.已完成;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);

            // 提交更改
            await DC.SaveChangesAsync();

            // 完成事务
            transactionScope.Complete();

            logger.LogInformation("转正申请完成操作执行成功，工号：{StaffNo}", Entity.StaffNo);
        }
        catch (Exception e)
        {
            logger.LogError(e, "执行转正申请完成操作时发生异常：{Message}", e.Message);
            throw;
        }
    }


    /*[WorkflowOperation("完成并更新档案", "将流程状态设置为已完成并更新人员转正信息", "转正申请")]
    public async Task CompleteAndUpdateArchive(ActivityExecutionContext context)
    {
        // 启用隐式分布式事务
        System.Transactions.TransactionManager.ImplicitDistributedTransactions = true;

        // 获取日志记录器
        using var scope = Wtm.ServiceProvider.CreateScope();
        var logger = scope.ServiceProvider.GetRequiredService<ILogger<SysHrProbationRequestBillVm>>();

        // 获取当前操作用户
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
        {
            currentUser = input.CurrentUser?.ITCode ?? "workflow";
        }

        logger.LogInformation("开始执行转正申请完成操作，单据ID：{EntityId}，原工号：{StaffNo}，转正后工号：{RegularStaffNo}，操作用户：{User}",
            Entity?.ID, Entity?.StaffNo, Entity?.RegularStaffNo, currentUser);

        // 使用 TransactionScope 替代 Database.BeginTransactionAsync
        using var transactionScope = new System.Transactions.TransactionScope(
            System.Transactions.TransactionScopeOption.Required,
            new System.Transactions.TransactionOptions
            {
                IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted,
                Timeout = TimeSpan.FromMinutes(5)
            },
            System.Transactions.TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            // 更新单据状态
            if (Entity is IBasePoco poco)
            {
                poco.UpdateTime = DateTime.Now;
                DC.UpdateProperty(Entity, x => x.UpdateTime);
                poco.UpdateBy = currentUser;
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }

            if (Entity is IBill bill)
            {
                bill.WorkflowStatus = WorkflowStatus.已完成;
                DC.UpdateProperty(Entity, x => x.WorkflowStatus);
            }

            // 检查是否有转正后工号
            if (string.IsNullOrEmpty(Entity.RegularStaffNo))
            {
                logger.LogError("转正后工号为空，无法完成转正操作");
                throw new Exception("转正后工号不能为空");
            }

            // 检查当前工号是否是负数
            if (!string.IsNullOrEmpty(Entity.StaffNo) && int.TryParse(Entity.StaffNo, out int staffNoValue) &&
                staffNoValue > 0)
            {
                logger.LogError("当前工号 {StaffNo} 已转正，无法完成转正操作", Entity.StaffNo);
                throw new Exception($"当前工号 {Entity.StaffNo} 无效，无法完成转正操作");
            }

            // 1. 更新人员档案的工号和转正信息
            if (!string.IsNullOrEmpty(Entity.StaffNo))
            {
                var updatedPersonRows = await DC.Set<SysPerson>()
                    .Where(x => x.GetType() == typeof(SysPerson))
                    .Where(p => p.StaffNo == Entity.StaffNo)
                    .ExecuteUpdateAsync(p => p
                        .SetProperty(x => x.StaffNo, Entity.RegularStaffNo)
                        .SetProperty(x => x.State, PersonState.在职)
                        .SetProperty(x => x.HireDate, Entity.EntryDate ?? DateTime.Now)
                        .SetProperty(x => x.ConfirmationDate, Entity.RegDate ?? DateTime.Now)
                        .SetProperty(x => x.UpdateTime, DateTime.Now)
                        .SetProperty(x => x.CreateBy, Entity.RegularStaffNo)
                        .SetProperty(x => x.UpdateBy, currentUser));

                if (updatedPersonRows > 0)
                {
                    logger.LogInformation(
                        "成功更新人员档案信息，原工号：{OriginalStaffNo}，新工号：{NewStaffNo}，转正日期：{RegularDate}，影响行数：{Count}",
                        Entity.StaffNo, Entity.RegularStaffNo, Entity.RegDate ?? DateTime.Now, updatedPersonRows);
                }
                else
                {
                    logger.LogWarning("未找到工号为 {StaffNo} 的人员档案", Entity.StaffNo);
                }

                // 2. 更新系统账号的工号
                var updatedUserRows = await DC.Set<FrameworkUser>()
                    .Where(u => u.ITCode == Entity.StaffNo)
                    .ExecuteUpdateAsync(u => u
                        .SetProperty(x => x.ITCode, Entity.RegularStaffNo)
                        .SetProperty(x => x.UpdateTime, DateTime.Now)
                        .SetProperty(x => x.UpdateBy, currentUser));

                if (updatedUserRows > 0)
                {
                    logger.LogInformation("成功更新系统账号工号，原工号：{OriginalStaffNo}，新工号：{NewStaffNo}，影响行数：{Count}",
                        Entity.StaffNo, Entity.RegularStaffNo, updatedUserRows);
                }
                else
                {
                    logger.LogWarning("未找到工号为 {StaffNo} 的系统账号", Entity.StaffNo);
                }

                // 3. 更新用户角色表中的用户代码
                var updatedUserRoleRows = await DC.Set<FrameworkUserRole>()
                    .Where(ur => ur.UserCode == Entity.StaffNo)
                    .ExecuteUpdateAsync(ur => ur
                        .SetProperty(x => x.UserCode, Entity.RegularStaffNo)
                        .SetProperty(x => x.UpdateTime, DateTime.Now)
                        .SetProperty(x => x.UpdateBy, currentUser));

                if (updatedUserRoleRows > 0)
                {
                    logger.LogInformation("成功更新用户角色关联，原工号：{OriginalStaffNo}，新工号：{NewStaffNo}，影响行数：{Count}",
                        Entity.StaffNo, Entity.RegularStaffNo, updatedUserRoleRows);
                }

                // 4. 更新用户部门表中的用户代码
                var updatedUserGroupRows = await DC.Set<FrameworkUserGroup>()
                    .Where(ug => ug.UserCode == Entity.StaffNo)
                    .ExecuteUpdateAsync(ug => ug
                        .SetProperty(x => x.UserCode, Entity.RegularStaffNo)
                        .SetProperty(x => x.UpdateTime, DateTime.Now)
                        .SetProperty(x => x.UpdateBy, currentUser));

                if (updatedUserGroupRows > 0)
                {
                    logger.LogInformation("成功更新用户部门关联，原工号：{OriginalStaffNo}，新工号：{NewStaffNo}，影响行数：{Count}",
                        Entity.StaffNo, Entity.RegularStaffNo, updatedUserGroupRows);
                }

                // 5. 清除用户缓存
                await Wtm.RemoveUserCache(Entity.StaffNo, Entity.RegularStaffNo);
                logger.LogInformation("已清除用户缓存，工号：{OriginalStaffNo} 和 {NewStaffNo}", Entity.StaffNo,
                    Entity.RegularStaffNo);
            }

            // 提交所有更改
            await DC.SaveChangesAsync();

            // 完成事务
            transactionScope.Complete();

            logger.LogInformation("转正申请完成操作执行成功，工号已从 {OriginalStaffNo} 更新为 {NewStaffNo}",
                Entity.StaffNo, Entity.RegularStaffNo);
        }
        catch (Exception e)
        {
            logger.LogError(e, "执行转正申请完成操作时发生异常：{Message}", e.Message);
            // TransactionScope 会自动回滚
            throw;
        }
    }*/
}